package pl.chopin.model.loader;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import pl.chopin.model.Line;
import pl.chopin.model.LinePosition;
import pl.chopin.model.Sail;
import pl.chopin.model.Stand;

/**
 * Ta klasa musi dostarczac list obiektow odczytanych z xml'i. Prawie zrobilem z
 * niego singleton.
 */
public class ModelFactory {

	/* ====== STATYCZNE ======= */
	private static SAXReader saxReader = new SAXReader();
	private static final String resourcesPath = "resources"
			+ System.getProperty("file.separator") + "model"
			+ System.getProperty("file.separator");

	private static ModelFactory instance;

	public static ModelFactory getInstance() {
		if (instance == null) {
			instance = new ModelFactory();
		}
		return instance;
	}

	/* ===== DYNAMICZNE ======= */
	private List<Stand> stands;
	private List<LinePosition> linePositions;
	private List<Line> lines;
	private List<Sail> sails;

	public ModelFactory() {
		stands = initStands();
		linePositions = initLinePositions();
		lines = initLines(stands, linePositions);
		sails = initSails(lines);
	}

	public List<Line> getLines() {
		return lines;
	}

	/**
	 * metodka pomocnicza do wyszukiwania instancji liny o konkretnym id
	 */
	public Line getLineFromListById(String id) {
		for (Line line : lines) {
			if (line.getId().equals(id))
				return line;
		}
		return null;
	}

	public List<Sail> getSails() {
		return sails;
	}

	/** inicjacja lin */
	private List<Line> initLines(List<Stand> stands2,
			List<LinePosition> linePositions2) {
		Document document = null;
		List<Line> lineList = new ArrayList<Line>();
		try {
			document = saxReader.read(resourcesPath + "lines.xml");

			for (Iterator i = document.selectNodes("//line").iterator(); i
					.hasNext();) {
				Node n = (Node) i.next();
				Line tmp = new Line();
				tmp.setId(n.selectSingleNode("id").getText());
				tmp.setName(n.selectSingleNode("name").getText());
				lineList.add(tmp);

			}
		} catch (DocumentException e) {
			e.printStackTrace();
			return null;
		}
		return lineList;
	}

	/** inicjacja zagli ZAKLADA ZE LINY SA JUZ ZAINICJALIZOWANE */
	private List<Sail> initSails(List<Line> lines2) {
		Document document = null;
		List<Sail> sailsList = new ArrayList<Sail>();
		try {
			document = saxReader.read(resourcesPath + "sails.xml");

			for (Iterator i = document.selectNodes("//sail").iterator(); i
					.hasNext();) {
				Node n = (Node) i.next();
				Sail tmp = new Sail();

				// najpierw ogolne
				tmp.setId(n.selectSingleNode("id").getText());
				tmp.setName(n.selectSingleNode("name").getText());

				// brasy
				tmp.setLeftBrace(getLineFromListById(n.selectSingleNode(
						"leftBrace").getText()));
				tmp.setRightBrace(getLineFromListById(n.selectSingleNode(
						"rightBrace").getText()));

				// gejtawy
				tmp.setLeftDewline(getLineFromListById(n.selectSingleNode(
						"leftDewline").getText()));
				tmp.setRightDewline(getLineFromListById(n.selectSingleNode(
						"rightDewline").getText()));

				// szoty
				tmp.setLeftSheet(getLineFromListById(n.selectSingleNode(
						"leftSheet").getText()));
				tmp.setRightSheet(getLineFromListById(n.selectSingleNode(
						"rightSheet").getText()));

				// halsy - jesli sa
				Node node = n.selectSingleNode("leftTackline");
				if (node != null) {
					tmp.setLeftTackline(getLineFromListById(node.getText()));
				}
				node = n.selectSingleNode("rightTackline");
				if (node != null) {
					tmp.setRightTackline(getLineFromListById(node.getText()));
				}

				// gordingi sa na liscie trzeba sie wiec przeiterowac
				tmp.setLeftBuntlines(new ArrayList<Line>());
				for (Object buntlineObject : n
						.selectNodes("//leftBuntlines/buntline")) {
					Node buntlineNode = (Node) buntlineObject;
					tmp.getLeftBuntlines().add(
							getLineFromListById(buntlineNode.getText()));
				}

				tmp.setRightBuntlines(new ArrayList<Line>());
				for (Object buntlineObject : n
						.selectNodes("//rightBuntlines/buntline")) {
					Node buntlineNode = (Node) buntlineObject;
					tmp.getRightBuntlines().add(
							getLineFromListById(buntlineNode.getText()));
				}

				sailsList.add(tmp);

			}
		} catch (DocumentException e) {
			e.printStackTrace();
			return null;
		}

		return sailsList;
	}

	private List<LinePosition> initLinePositions() {
		// TODO Auto-generated method stub
		return null;
	}

	private List<Stand> initStands() {
		// TODO Auto-generated method stub
		return null;
	}
}
